package com.baidu.ueditor.hunter;

import java.net.HttpURLConnection;
import java.net.InetAddress;
import java.net.URL;
import java.net.UnknownHostException;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

import com.baidu.ueditor.PathFormat;
import com.baidu.ueditor.define.AppInfo;
import com.baidu.ueditor.define.BaseState;
import com.baidu.ueditor.define.MIMEType;
import com.baidu.ueditor.define.MultiState;
import com.baidu.ueditor.define.State;
import com.baidu.ueditor.upload.StorageManager;

/**
 * 图片抓取器
 * 
 * @author hancong03@baidu.com
 *
 */
public class ImageHunter{

    private String filename = null;
    private String savePath = null;
    private String rootPath = null;
    private List<String> allowTypes = null;
    private long maxSize = -1;

    private List<String> filters = null;

    public ImageHunter(Map<String, Object> conf){

        this.filename = (String) conf.get("filename");
        this.savePath = (String) conf.get("savePath");
        this.rootPath = (String) conf.get("rootPath");
        this.maxSize = (Long) conf.get("maxSize");
        this.allowTypes = Arrays.asList((String[]) conf.get("allowFiles"));
        this.filters = Arrays.asList((String[]) conf.get("filter"));

    }

    public State capture(String[] list){

        MultiState state = new MultiState(true);

        for(String source : list){
            state.addState(captureRemoteData(source));
        }

        return state;

    }

    public State captureRemoteData(String urlStr){

        HttpURLConnection connection = null;
        URL url = null;
        String suffix = null;

        try{
            url = new URL(urlStr);

            if(!validHost(url.getHost())){
                return new BaseState(false, AppInfo.PREVENT_HOST);
            }

            connection = (HttpURLConnection) url.openConnection();

            connection.setInstanceFollowRedirects(true);
            connection.setUseCaches(true);

            if(!validContentState(connection.getResponseCode())){
                return new BaseState(false, AppInfo.CONNECTION_ERROR);
            }

            suffix = MIMEType.getSuffix(connection.getContentType());

            if(!validFileType(suffix)){
                return new BaseState(false, AppInfo.NOT_ALLOW_FILE_TYPE);
            }

            if(!validFileSize(connection.getContentLength())){
                return new BaseState(false, AppInfo.MAX_SIZE);
            }

            String savePath = this.getPath(this.savePath, this.filename, suffix);
            String physicalPath = this.rootPath + savePath;

            State state = StorageManager.saveFileByInputStream(connection.getInputStream(),
                    physicalPath);

            if(state.isSuccess()){
                state.putInfo("url", PathFormat.format(savePath));
                state.putInfo("source", urlStr);
            }

            return state;

        }catch(Exception e){
            return new BaseState(false, AppInfo.REMOTE_FAIL);
        }

    }

    private String getPath(String savePath, String filename, String suffix){

        return PathFormat.parse(savePath + suffix, filename);

    }

    private boolean validHost(String hostname){
        try{
            InetAddress ip = InetAddress.getByName(hostname);

            if(ip.isSiteLocalAddress()){
                return false;
            }
        }catch(UnknownHostException e){
            return false;
        }

        return !filters.contains(hostname);

    }

    private boolean validContentState(int code){

        return HttpURLConnection.HTTP_OK == code;

    }

    private boolean validFileType(String type){

        return this.allowTypes.contains(type);

    }

    private boolean validFileSize(int size){
        return size < this.maxSize;
    }

}
